package com.eastfair.venuebooking.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.venuebooking.dao.ExhibitionSpaceMapper;
import com.eastfair.venuebooking.dto.ExhibitionSpaceDTO;
import com.eastfair.venuebooking.dto.QuotationDetailDTO;
import com.eastfair.venuebooking.entity.ExhibitionSpace;
import com.eastfair.venuebooking.exceptioncode.VenueBookingExceptionCode;
import com.eastfair.venuebooking.service.ExhibitionSpaceService;
import com.eastfair.venuebooking.service.QuotationService;
import com.eastfair.venuebooking.vo.ExhibitionSpaceVO;
import com.eastfair.venuebooking.vo.QuotationDetailVO;
import com.eastfair.venuebooking.vo.QuotationVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 业务实现类
 * 展会预定场地表
 * </p>
 *
 * @author gj
 * @date 2022-07-22
 */
@Slf4j
@Service
public class ExhibitionSpaceServiceImpl extends SuperServiceImpl<ExhibitionSpaceMapper, ExhibitionSpace> implements ExhibitionSpaceService {

    @Resource
    private QuotationService quotationService;

    @Resource
    private ExhibitionSpaceMapper exhibitionSpaceMapper;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ExhibitionSpace> modelList) {
        modelList.forEach(s -> s.setIsDeleted(BusinessConstant.YES));
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ExhibitionSpace model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public List<ExhibitionSpaceVO> listExhibitionSpaceVOs(ExhibitionSpaceDTO query) {
        log.info("listExhibitionSpaceVOs - 查询场地列表V, query={}", query);
        QueryWrapper<ExhibitionSpace> queryWrapper = createExhibitionSpaceQueryWrapper(query);
        return exhibitionSpaceMapper.listExhibitionSpaceVOs(queryWrapper);
    }

    @Override
    public List<ExhibitionSpace> listExhibitionSpaces(ExhibitionSpaceDTO query) {
        log.info("listExhibitionSpaces - 查询展会场地列表, query={}", query);
        QueryWrapper<ExhibitionSpace> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(query.getExhibitionId() != null, ExhibitionSpace::getExhibitionId, query.getExhibitionId())
                .in(query.getSpaceIdList() != null && !query.getSpaceIdList().isEmpty(),
                        ExhibitionSpace::getSpaceId, query.getSpaceIdList())
                .eq(ExhibitionSpace::getIsDeleted, BusinessConstant.DELETE_NO)
        ;
        return list(queryWrapper);
    }

    @Override
    public List<ExhibitionSpace> listExhibitionSpacesByExhibitionId(List<ExhibitionSpaceDTO> list) {
        List<Long> spaceIdList = list
                .stream()
                .map(ExhibitionSpaceDTO::getSpaceId)
                .collect(Collectors.toList());
        ExhibitionSpaceDTO query = new ExhibitionSpaceDTO();
        query.setSpaceIdList(spaceIdList);
        query.setExhibitionId(list.get(0).getExhibitionId());
        return listExhibitionSpaces(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExhibitionSpace(ExhibitionSpaceDTO saveDTO) {
        log.info("saveExhibitionSpace - 保存展会场地");
        // 校验是否存在
        ExhibitionSpace exhibitionSpace = BeanUtil.toBean(saveDTO, ExhibitionSpace.class);
        return save(exhibitionSpace);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatchExhibitionSpace(List<ExhibitionSpaceDTO> list) {
        log.info("saveBatchExhibitionSpace - 批量保存展会场地");
        // 校验展会是否存在相同的场地
        List<ExhibitionSpace> existList = listExhibitionSpacesByExhibitionId(list);
        if (existList != null && !existList.isEmpty()) {
            throw BizException.wrap(VenueBookingExceptionCode.EX_QUO_EXIST_SPACE);
        }
        list.forEach(this::saveExhibitionSpace);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveBatchByQuotationDetailList(List<QuotationDetailDTO> list, Long exhibitionId) {
        log.info("saveBatchByQuotationDetailList - 通过报价书详情列表批量保存展会场地, list={}, exhibitionId={}", list, exhibitionId);
        List<ExhibitionSpaceDTO> exhibitionSpaceDTOList = list
                .stream()
                .map(quotationDetailDTO -> {
                    ExhibitionSpaceDTO exhibitionSpaceDTO = new ExhibitionSpaceDTO();
                    exhibitionSpaceDTO.setExhibitionId(exhibitionId);
                    exhibitionSpaceDTO.setSpaceId(quotationDetailDTO.getSpaceId());
                    exhibitionSpaceDTO.setSpaceName(quotationDetailDTO.getSpaceName());
                    return exhibitionSpaceDTO;
                })
                .collect(Collectors.toList());
        return saveBatchExhibitionSpace(exhibitionSpaceDTOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByExhibitionIdAndSpaceIds(Long exhibitionId, List<Long> spaceIdList) {
        log.info("removeBatchByExhibitionIdAndSpaceIds - 展会ID与场地ID列表删除展会场地, exhibitionId={}, spaceIdList={}",
                exhibitionId, spaceIdList);
        ExhibitionSpaceDTO query = new ExhibitionSpaceDTO();
        query.setExhibitionId(exhibitionId);
        query.setSpaceIdList(spaceIdList);
        List<ExhibitionSpace> exhibitionSpaces = listExhibitionSpaces(query);
        List<Long> ids = exhibitionSpaces
                .stream()
                .map(SuperEntity::getId)
                .collect(Collectors.toList());
        return removeByIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeBatchByQuotationIds(List<Long> quotationIds) {
        log.info("removeBatchByQuotationIds - 报价书ID列表删除展会场地, quotationIds={}", quotationIds);
        if (quotationIds == null || quotationIds.isEmpty()) {
            return false;
        }
        boolean remove = true;
        for (Long quotationId : quotationIds) {
            QuotationVO quotationVO = quotationService.getQuotationVOById(quotationId);
            List<QuotationDetailVO> quotationDetailList = quotationVO.getQuotationDetailList();
            Long exhibitionId = quotationVO.getExhibitionId();
            if (exhibitionId == null) {
                continue;
            }
            List<Long> spaceIds = quotationDetailList
                    .stream()
                    .map(QuotationDetailVO::getSpaceId)
                    .collect(Collectors.toList());
            if (!spaceIds.isEmpty()) {
                remove = remove & removeBatchByExhibitionIdAndSpaceIds(exhibitionId, spaceIds);
            }
        }
        return remove;
    }

    /**
     * 创建QueryWrapper
     *
     * @param query 查询参数
     * @return QueryWrapper.
     */
    private QueryWrapper<ExhibitionSpace> createExhibitionSpaceQueryWrapper(ExhibitionSpaceDTO query) {
        QueryWrapper<ExhibitionSpace> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq(query.getExhibitionId() != null, "es.exhibition_id", query.getExhibitionId())
                .in(query.getSpaceIdList() != null && !query.getSpaceIdList().isEmpty(),
                        "es.space_id", query.getSpaceIdList())
                .eq("es.is_deleted", BusinessConstant.DELETE_NO)
        ;
        return queryWrapper;
    }
}
